package com.jshan.blog.security;

import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.jshan.blog.iterceptor.MySaInterceptor;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.TimeZone;

/**
 * @ClassName SaTokenConfig
 * @Author jshan
 * @Date 2024/1/22 16:36
 * @Version 1.0
 */
@Slf4j
@Configuration
@RequiredArgsConstructor
public class SaTokenConfig implements WebMvcConfigurer {

    @Resource
    private final WhitelistProperties whitelistProperties;
    @Autowired
    private ObjectProvider<HttpMessageConverters> messageConverters;

    @Bean
    public StpLogic getStpLogicJwt() {
        // Sa-Token 整合 jwt (简单模式)
        return new StpLogicJwtForSimple();
    }
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(0,  mappingJackson2HttpMessageConverter()); // 优先使用自定义转换器
    }

    // 修改后的 mappingJackson2HttpMessageConverter 方法
    private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        ObjectMapper objectMapper = new ObjectMapper();

        // 基础配置
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,  false);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

        // 时间模块配置（核心）
        JavaTimeModule javaTimeModule = new JavaTimeModule();

        // LocalDate 序列化/反序列化
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        javaTimeModule.addSerializer(LocalDate.class,  new LocalDateSerializer(dateFormatter));
        javaTimeModule.addDeserializer(LocalDate.class,  new LocalDateDeserializer(dateFormatter));

        // LocalDateTime 序列化/反序列化
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd  HH:mm:ss");
        javaTimeModule.addSerializer(LocalDateTime.class,  new LocalDateTimeSerializer(dateTimeFormatter));
        javaTimeModule.addDeserializer(LocalDateTime.class,  new LocalDateTimeDeserializer(dateTimeFormatter));

        objectMapper.registerModule(javaTimeModule);

        // 时区配置
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));

        return new MappingJackson2HttpMessageConverter(objectMapper);
    }

    @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                // 保持原有拦截器配置
                log.info(" 注册白名单:{}", whitelistProperties.getWhitelist());
                registry.addInterceptor(new  SaInterceptor(r -> StpUtil.checkLogin()))
                        .order(1)
                        .addPathPatterns("/**")
                        .excludePathPatterns(whitelistProperties.getWhitelist());

                registry.addInterceptor(new  MySaInterceptor())
                        .order(2)
                        .addPathPatterns("/**")
                        .excludePathPatterns(whitelistProperties.getWhitelist());
            }
        };
    }



}
